#ifndef ENUM_UTIL_HPP
#define ENUM_UTIL_HPP

#define UTIL_ENUM_ELEMENT(x) x,
#define UTIL_ENUM_STRING(x) #x,

#include <type_traits>
#include <string>

/// The ENUM macro defines a strongly-typed enum with the given elements
/// along with a toString() method
#define ENUM(name, elements)                                           \
    enum class name { elements(UTIL_ENUM_ELEMENT) };                   \
    inline const char* toString(name e) {                              \
        static const char* strings[] = { elements(UTIL_ENUM_STRING) }; \
        return strings[static_cast<std::underlying_type<name>::type>(e)];  \
    }

#endif
